package masterjava.common.client.gxt.base.util;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;
import java.util.Iterator;

/**
 * User: gkislin
 * Date: 7/20/11
 * <p/>
 * JavaScriptObject wrapper
 */
public class JsonObject extends JSONObject {

    public JsonObject() {
    }

    public static JsonObject getClone(JSONObject clone) {
        return new JsonObject(clone.toString());
    }

    public JsonObject(String data) {
        super(ScriptUtil.evalJsonObject(data));
    }

    public JsonObject(JSONObject jsonObject) {
        super(jsonObject.getJavaScriptObject());
    }

    public JsonObject(JavaScriptObject jso) {
        super(jso);
    }

    public void removeProperty(String path) {
        setProperty(path, null);
    }

    /**
     *
     * @param path : path to property in form of ".../.../..."
     * @param value: value. if null- remove property
     */
    public void setProperty(String path, @Nullable Object value) {
        String[] items = path.split("/");
        String item = null;
        JSONObject parentResult = this;

        if (items.length == 1) {
            item = items[0];
        } else {
            Iterator<String> iter = Arrays.asList(items).iterator();
            while (iter.hasNext()) {
                item = iter.next();
                if (!iter.hasNext()) {
                    break;
                }
                JSONValue jsonValue = parentResult.get(item);
                if (jsonValue instanceof JSONObject) {
                    parentResult = ((JSONObject) jsonValue);
                } else {
                    JSONObject newValue = new JSONObject();
                    parentResult.put(item, newValue);
                    parentResult = newValue;
                }
            }
        }
        if (value==null || value instanceof JSONValue) {
            parentResult.put(item, (JSONValue) value);
        } else {
            ScriptUtil.getJsObject(parentResult.getJavaScriptObject()).set(item, value);
        }
    }

    public JSONValue getProperty(String path) {
        String[] items = path.split("/");
        JSONValue result = this;
        for (String item : items) {
            if (result instanceof JSONObject) {
                result = ((JSONObject) result).get(item);
            } else {
                return null;
            }
        }
        return result;
    }
}
